package com.liankuan.console.util;

import com.liankuan.console.common.ResultEnum;
import com.liankuan.console.dto.Strategy;
import com.liankuan.console.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@Component
public class ReadFileUtil {

    @Autowired
    private Config config;

    /**
     * 获取日志信息
     *
     * @param pageNumber
     * @param pageSize
     * @param strategy
     * @return
     */
    public HashMap lodingLogFile(int pageNumber, int pageSize, Strategy strategy) {
        HashMap<String, Object> retMap;
        String single = "log";
        String filename;
        if (config.getEnv().equals("pro")) {
            String strategyName = strategy.getJarName().substring(0, strategy.getJarName().length() - 4) + "-" +
                    strategy
                            .getId();

            filename = String.format(config.getLogPath(), strategyName);
        } else {
            //TODO 测试
            filename = String.format(config.getLogPath());
        }

        if (pageNumber == 1) {
            retMap = initRead(filename, pageSize, single);
        } else {
            retMap = getPageData(filename, pageSize, pageNumber, single);
        }
        return retMap;
    }

    /**
     * 初始化请求
     *
     * @param filename
     * @param pageSize
     * @return
     */
    private HashMap<String, Object> initRead(String filename, int pageSize, String single) {
        HashMap<String, Object> retMap = new HashMap<String, Object>();

        long lineCount = 0; // 日志文件总行数
        LineNumberReader reader = null;
        ArrayList<String> lineArr = new ArrayList<String>();
        int lines = 0;
        try {
            lineCount = getFileLineCounts(filename);

            reader = new LineNumberReader(new FileReader(filename));
            String lineStr = "";
            while (lines < lineCount) {
                lineStr = reader.readLine();
                lines++;
                if (lineStr == null || lines > lineCount) {
                    break;
                } else if (lines > lineCount - pageSize) {
                    lineArr.add(lineStr);
                }
            }
            //只有日志文件需要翻转输出
            if ("log".equals(single)) {
                Collections.reverse(lineArr);
            }
        } catch (Exception ex) {
            // TODO 返回空
            retMap.put("total", 0);
            retMap.put("data", Collections.emptyList());
            return retMap;
        } finally {
            try {
                reader.close();
            } catch (Exception ex) {
                // TODO 返回空
                retMap.put("total", 0);
                retMap.put("data", Collections.emptyList());
                return retMap;
            }
        }

        retMap.put("total", lineCount);
        retMap.put("data", lineArr);
        return retMap;
    }

    /**
     * 获取最新生成的日志
     *
     * @param lastLine
     * @return
     */
    public HashMap<String, Object> getNewLogData(Strategy strategy, int lastLine) {
        String filename;
        if (config.getEnv().equals("pro")) {
            String strategyName = strategy.getJarName().substring(0, strategy.getJarName().length() - 4) + "-" +
                    strategy.getId();

            filename = String.format(config.getLogPath(), strategyName);
        } else {
            //TODO 测试
            filename = String.format(config.getLogPath());
        }
        return getNewInfo(strategy, lastLine, filename, "log");


    }


    public HashMap<String, Object> getNewInfo(Strategy strategy, int lastLineNumber, String filename, String single) {
        HashMap<String, Object> retMap = new HashMap<String, Object>();
        LineNumberReader reader = null;
        ArrayList<String> lineArr = new ArrayList<String>();
        int lines = 0;
        try {
            reader = new LineNumberReader(new FileReader(filename));
            String lineStr = "";
            while (lineStr != null) {
                lineStr = reader.readLine();
                lines++;
                if (lines > lastLineNumber && lineStr != null) {
                    lineArr.add(lineStr);
                }
            }
            if (single.equals("log")) {
                Collections.reverse(lineArr);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        long total = getFileLineCounts(filename);
        retMap.put("total", total);
        retMap.put("data", lineArr);
        return retMap;
    }


    /**
     * 获取最新生成的收益曲线日志
     *
     * @param lastLine
     * @return
     */
    public HashMap<String, Object> getNewProfitData(Strategy strategy, int lastLine) {

        String filename;
        if (config.getEnv().equals("pro")) {
            String strategyName = strategy.getJarName().substring(0, strategy.getJarName().length() - 4) + "-" +
                    strategy
                            .getId();
            filename = String.format(config.getProfitPath(), strategyName);
        } else {
            //TODO  测试环境
            filename = config.getProfitPath();
        }


        return getNewInfo(strategy, lastLine, filename, "profit");
    }

    /**
     * 获取收益曲线
     *
     * @param pageNumber
     * @param pageSize
     * @param strategy
     * @return
     */
    public HashMap lodingPrefitLog(int pageNumber, int pageSize, Strategy strategy) {
        HashMap<String, Object> retMap;
        String single = "profit";

        //TODO 正式环境
        String fileName;
        if (config.getEnv().equals("pro")) {
            String strategyName = strategy.getJarName().substring(0, strategy.getJarName().length() - 4) + "-" +
                    strategy
                            .getId();
            fileName = String.format(config.getProfitPath(), strategyName);
        } else {
            fileName = config.getProfitPath();
        }

        if (pageNumber == 1) {
            retMap = initRead(fileName, pageSize, single);
        } else {
            retMap = getPageData(fileName, pageSize, pageNumber, single);
        }
        return retMap;
    }

    /**
     * 获取指定页日志数据
     *
     * @param filename
     * @param pageSize
     * @param pageNumber
     * @return
     */
    private HashMap<String, Object> getPageData(String filename, int pageSize, int pageNumber, String single) {
        HashMap<String, Object> retMap = new HashMap<String, Object>();
        ArrayList<String> lineArr = new ArrayList<String>();
        int lines = 0;

        long lineCount = getFileLineCounts(filename);
        int pageCount = (int) Math.ceil(lineCount / pageSize);
        if (pageNumber <= pageCount) {
            int startLineNumber = (pageCount - pageNumber) * pageSize;
            LineNumberReader reader = null;
            try {
                reader = new LineNumberReader(new FileReader(filename));
                String lineStr = "";
                while (lineStr != null) {
                    lineStr = reader.readLine();
                    lines++;
                    if (lines > startLineNumber && lineStr != null && lineArr.size() < pageSize) {
                        lineArr.add(lineStr);
                    }
                }
                if ("log".equals(single)) {
                    Collections.reverse(lineArr);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                try {
                    reader.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        retMap.put("data", lineArr);
        retMap.put("total", getFileLineCounts(filename));
        return retMap;
    }

    /**
     * 获取文件总行数
     *
     * @param filename
     * @return
     */
    private long getFileLineCounts(String filename) {
        long lineCount = 0;
        InputStream is = null;
        try {
            is = new BufferedInputStream(new FileInputStream(filename));
            byte[] c = new byte[1024];
            int readChars = 0;
            while ((readChars = is.read(c)) != -1) {
                for (int i = 0; i < readChars; ++i) {
                    if (c[i] == '\n') {
                        ++lineCount;
                    }
                }
            }
        } catch (Exception ex) {
            lineCount = -1;
            ex.printStackTrace();

            // TODO
            return 0;
        } finally {
            try {
                is.close();
            } catch (Exception ex) {
                return 0;
            }
        }
        return lineCount;
    }

    /**
     * 目前用来读取jar包指定文件的运行状态
     *
     * @param filePath
     * @return
     */
    public static String getJarState(String filePath) {
        BufferedReader reader = null;
        String sate;
        try {
            reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(filePath)));

            sate = reader.readLine();
            return sate;
        } catch (Exception e) {
            throw new ServiceException(ResultEnum.READ_FILE_FAILED);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 目前用来读取jar包指定文件的运行状态
     *
     * @param filePath
     * @return
     */
    public static List<String> getUpdateJarState(String filePath) {
        LineNumberReader reader = null;
        ArrayList<String> lineArr = new ArrayList<String>();
        try {
            reader = new LineNumberReader(new FileReader(filePath));
            String lineStr = "";
            while (lineStr != null) {
                lineStr = reader.readLine();
                lineArr.add(lineStr);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        return lineArr;
    }


    /**
     * 用来读取整个文件内容
     *
     * @param filePath
     */
    public static StringBuilder readTxtFile(String filePath) {
        int len = 0;
        StringBuilder str = new StringBuilder("");
        File file = new File(filePath);
        try {
            FileInputStream is = new FileInputStream(file);
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader in = new BufferedReader(isr);
            String line = null;
            while ((line = in.readLine()) != null) {
                if (len != 0)  // 处理换行符的问题
                {
                    str.append("\r\n" + line);
                } else {
                    str.append(line);
                }
                len++;
            }
            in.close();
            is.close();
        } catch (IOException e) {
            return null;
//            throw new ServiceException(ResultEnum.NOT_FILE_PATH);
        }
        return str;

    }

    /**
     * 下载日志文件
     * @param request
     * @param response
     * @param strategy
     * @return
     */
    public String downloadFile(HttpServletRequest request, HttpServletResponse response,Strategy strategy) {
        String fileName;
        if (config.getEnv().equals("pro")) {
            String strategyName = strategy.getJarName().substring(0, strategy.getJarName().length() - 4) + "-" +
                    strategy.getId();

            fileName = String.format(config.getLogPath(), strategyName);
        } else {
            //TODO 测试
            fileName = String.format(config.getLogPath());
        }
        if (fileName != null) {
            //设置文件路径
            File file = new File(fileName);
            //File file = new File(realPath , fileName);
            if (file.exists()) {
                response.setContentType("application/force-download");// 设置强制下载不打开
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    return "success";
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        throw new ServiceException(ResultEnum.NOT_FILE_PATH);
    }


}
